<?php
/**
 * fly
 * Copyright By 5920Team (http://www.5920.me)
 * User: yu@5920.me
 * Date: 13-9-27
 * Time: 上午12:19
 */
/**
 * Class Autoloader
 */
class Autoloader
{
    /**
     * @var array
     */
    static private $conf = array();

    /**
     * @var array
     */
    static public $mapping = array();
    /**
     * @var string
     */
    static private $cacheFileName = "classesMapping";

    /**
     * make classes mapping
     * @param $classesPath
     */
    static  private function makeMapping()
    {
        $classesPath = array_merge(self::$conf['fly_classes_path'], self::$conf['app_classes_path']);
        self::$mapping = array();
        $i = 0;
        while (isset($classesPath[$i]) && $files = scandir($classesPath[$i]))
        {
            foreach ($files as $file)
            {
                $currentFile = $classesPath[$i] . '/' . $file;

                if (is_file($currentFile))
                {/** file */
                    if (pathinfo($file,PATHINFO_EXTENSION) === 'php')
                    {
                        if (preg_match_all('~^\s*(?:abstract\s+|final\s+)?(?:class|interface)\s+(\w+).*~mi', trim(file_get_contents($currentFile)), $classes) > 0)
                        {
                            foreach ($classes[1] as $className)
                            {

                                self::$mapping[strtolower($className)] = $currentFile;
                            }
                        }

                    }

                }
                else if (substr($file,0,1) !== '.')
                {/** directory */
                    $classesPath[] = $currentFile;
                }
            }
            $i ++;
        }
    }

    /**
     * autoloader Run
     * @param array $classesPath
     * @param bool $cacheSwitch
     */
    static public function run(array $config)
    {
        self::$conf = $config;
        if (self::$conf['cache_switch'])
        {
            self::$mapping = C::read(self::$cacheFileName);
            if (self::$mapping === false)
            {/** cache file not found */
                self::makeMapping();
                C::write(self::$cacheFileName, self::$mapping);
            }
        }
        else
        {
            self::makeMapping();
        }


        spl_autoload_register(array('Autoloader', 'loadClass'));
    }

    /**
     * __autoload function
     * @param $className
     */
    static public function loadClass($className)
    {
        require self::$mapping[strtolower($className)];
    }

}